Home > CS2600: Systems Programming > Dynamic Memory Allocation using Pointers
We can use pointers to request memory on the fly at runtime.
malloc()
: Allocate block of memory.free()
: Deallocate that block of memory.free
ing it (to avoid accidentally dereferencing a junk value).Note: Check after allocation that memory was indeed allocated.
- Done by seeing if your pointer points to a valid memory location instead of NULL.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, *ptr = 0;
// Prompt user for array length
("Enter number of elements: ");
printf("%d", &n);
scanf// Dynamic memory allocation using malloc()
= malloc(n*sizeof(int));
ptr // Exit if no memory was allocated
if(ptr == NULL)
{
("\nError! Memory not allocated\n");
printfreturn 0;
}
// Prompt user for array elements
("\nEnter elements of array: \n");
printffor(int i = 0; i < n; i++) {
("%d", ptr+i);
scanf}
// Printing the array elements
("\nThe elements of the array are: ");
printffor(int i = 0; i < n; i++) {
("%d ",ptr[i]); // ptr[i] is same as *(ptr + i)
printf}
// Deallocate the block of memory
(ptr);
free// Print newline and return
("");
putsreturn 0;
}
malloc()
returns a void pointer, ptr = malloc(n*sizeof(int));
automatically promotes it to an int
pointer.ptr = (int *) malloc(n*sizeof(int));
Pointer to a Pointer: Declared with two *
symbols.
int main() {
int a = 10;
int *p1 = &a;
int **p2 = &p1;
("&a : Ox%u\n", &a);
printf("&p1: Ox%u\n", &p1);
printf(" - *p1: %d\n", *p1);
printf("&p2: Ox%u\n", &p2);
printf(" - *p2 : %u (garbage)\n", *p2);
printf(" - **p2: %d\n", **p2);
printfreturn 0;
}
Example Output:
&a : Ox278518276
&p1: Ox278518280
- *p1: 10
&p2: Ox278518288
- *p2 : 278518276 (garbage)
- **p2: 10
A multidimensional array can be thought of as an array of arrays.
**array
)
dynamically without bracket notion.#include <stdio.h>
#include <stdlib.h>
int main()
{
int **array;
int row, col;
("Give me rows and columns: \n");
printf("%d%d", &row, &col);
scanf// Allocate memory for the 1D array.
// - Note how we are doing sizeof(int *), not sizeof(int)!
= malloc(row * sizeof(int *));
array if (array == NULL)
{
("out of memory\n");
printf(1);
exit}
// Allocate memory for the rest of the 2D array.
for (int i = 0; i < row; i++)
{
*(array+i) = malloc(col * sizeof(int));
if(array[i] == NULL)
{
("out of memory\n");
printf(1);
exit}
}
// Assign values and print contents of array
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
*(*(array+i)+j) = i;
// ^ Same thing as array[i][j] = i;
("%d \t", *(*(array+i)+j));
printf}
("\n");
printf}
// Deallocate the array and exit
for (int i = 0; i < row; i++)
{
(*(array+i));
free}
(array);
free= NULL;
array return 0;
}
Instructions: Read each piece of code and determine the output of each numbered section.
- (Code with answers is provided below the uncommented code)
Question: Pointer Arithmetic
#include <stdio.h> int main() { int *p; int sample[3] = { -1, 6, 5 }; // I. = sample; p ("%d\n", *p); printf // II. *p = *(p)*3; ("%d\n", *p); printf // III. = ++p; p ("%d\n", *p); printf // IV. = p++; p ("%d\n", *p); printf // V. *p = *(p - 1); ("%d\n", *p); printf // VI. ++(*p); ("%d\n", *p); printf}
#include <stdio.h> int main() { int *p; int sample[3] = { -1, 6, 5 }; // I. Prints "-1" = sample; p ("%d\n", *p); printf // II. Prints "-3" (-1 x 3) *p = *(p)*3; ("%d\n", *p); printf // III. Prints "6" (pre-incremented returns x+1) = ++p; p ("%d\n", *p); printf // IV. Prints "6" (post-incremented returns x) = p++; p ("%d\n", *p); printf // V. Prints "-3" *p = *(p - 1); ("%d\n", *p); printf // VI. Prints "-2" (-3 + 1) ++(*p); ("%d\n", *p); printf}
Question: Pointer Confusion
#include <stdio.h> #include <stdlib.h> int main() { int *x, *y, *z, *a, b[3] = {-4, 5, -6}; = malloc(3 * sizeof(int)); a = a; x for (int k = 1; k < 4; k++) [k - 1] = k; a// I. ("%d\t%d\t%d\n", a[0], a[1], a[2]); printf = &b[2]; z = (++x) + 1; y *x = *x + 4; // II. ("%d\t%d\t%d\n", *x, *y, *z); printf *(--z) = *(y - 1) + *x; *(z + 1) = *(x + 1) - 3; // III. ("%d\n", *z); printf *y-- = (*++z) - (*&a[2]); // IV. ("%d\n", *y); printf // V. ("%d\n", *x + 2); printf for (int j = 0; j < 3; j++) { // VII. ("%d\t%d\n", a[j], b[j]); printf} (a); free= NULL; a return 0; }
#include <stdio.h> #include <stdlib.h> int main() { int *x, *y, *z, *a, b[3] = {-4, 5, -6}; = malloc(3 * sizeof(int)); a = a; x for (int k = 1; k < 4; k++) [k - 1] = k; a// I. 1 2 3 ("%d\t%d\t%d\n", a[0], a[1], a[2]); printf = &b[2]; z = (++x) + 1; y *x = *x + 4; // II. 6 3 -6 ("%d\t%d\t%d\n", *x, *y, *z); printf *(--z) = *(y - 1) + *x; *(z + 1) = *(x + 1) - 3; // III. 12 ("%d\n", *z); printf *y-- = (*++z) - (*&a[2]); // IV. 6 ("%d\n", *y); printf // V. 8 ("%d\n", *x + 2); printf for (int j = 0; j < 3; j++) { // VII. 1 -4 // 6 12 // -3 0 ("%d\t%d\n", a[j], b[j]); printf} (a); free= NULL; a return 0; }
void *malloc(size_t size);
malloc
: int *x = malloc(100);
void *calloc(size_t nmemb, size_t size);
malloc()
calloc
: int *x = calloc(0, sizeof(int));
void free(void *_Nullable ptr);
Example
free
: free(x);
void *realloc(void *_Nullable ptr, size_t size);
void *reallocarray(void *_Nullable ptr, size_t nmemb, size_t size);
relloc
will attempt to assign a new block of memory and copy the old block contents.realloc
#include <stdio.h>
#include <stdlib.h>
int main () {
char *str;
= (char *) malloc(15);
str
(str, "Hello, How are");
strcpy("String = %s, Address = %p\n", str, str);
printf
= realloc(str, 20);
str (str, " you?");
strcat("String = %s, Address = %p\n", str, str);
printf
(str);
freereturn(0);
}